<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>宝宝详情</title>
    <script src="config.js"></script>
    <link rel="stylesheet" href="css/bootstrap-icons.css">
    <style>
        [v-cloak] { display: none !important; }
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            background-color: #f5f5f5;
            color: #333;
            height: 100vh;
            /* overflow: auto; 允许页面滚动 */
        }
        .detail-page {
            min-height: 100vh;
            background-color: #fff;
            display: flex;
            flex-direction: column;
        }
        .detail-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 15px 30px;
            background-color: #f8f9fa;
            border-bottom: 1px solid #eee;
            flex-shrink: 0;
        }
        .header-left {
            display: flex;
            align-items: center;
            gap: 20px;
        }
        .header-right {
            display: flex;
            align-items: center;
            gap: 20px;
        }
        .user-info {
            display: flex;
            align-items: center;
            gap: 12px;
            padding: 8px 16px;
            background: #fff;
            border-radius: 8px;
            border: 1px solid #e9ecef;
        }
        .user-email {
            font-size: 14px;
            color: #666;
            font-weight: 500;
        }
        .btn-outline-secondary {
            background: transparent;
            border: 1px solid #6c757d;
            color: #6c757d;
            padding: 6px 12px;
            font-size: 12px;
        }
        .btn-outline-secondary:hover {
            background: #6c757d;
            color: white;
        }
        .btn-outline-primary {
            background: transparent;
            border: 1px solid #0d6efd;
            color: #0d6efd;
            padding: 6px 12px;
            font-size: 12px;
        }
        .btn-outline-primary:hover {
            background: #0d6efd;
            color: white;
        }
        .btn-sm {
            padding: 6px 12px;
            font-size: 12px;
        }
        .detail-title {
            font-size: 1.8rem;
            font-weight: bold;
            color: #2c3e50;
            margin: 0;
        }
        .detail-content {
            flex: 1;
            display: flex;
            padding: 20px 30px;
            gap: 20px;
            /* overflow: visible; 允许内容超出时页面滚动 */
        }

        /* 移动端适配 */
        @media (max-width: 768px) {
            .detail-header {
                padding: 15px 20px;
                flex-direction: column;
                gap: 15px;
                align-items: stretch;
            }
            
            .header-right {
                justify-content: center;
                gap: 10px;
            }
            
            .user-info {
                flex-direction: column;
                gap: 8px;
                text-align: center;
            }
            
            .detail-content {
            padding: 20px;
                flex-direction: column;
                gap: 20px;
        }
            
        .content {
            flex-direction: column;
                gap: 15px;
            }
            
            .left-panel {
                width: 100%;
            }
            
            .photo-container {
                height: 250px;
            }
            
            .info-section {
                padding: 20px;
            }
            
            .info-grid {
                grid-template-columns: repeat(2, 1fr);
                gap: 15px;
            }
            
            .info-item {
                padding: 15px;
            }
            
            .charts-container {
                grid-template-columns: 1fr;
                gap: 15px;
            }
            
            .chart {
                height: 300px;
            }
            
            .detail-title {
                font-size: 1.4rem;
            }
        }

        @media (max-width: 480px) {
            .detail-header {
                padding: 10px 15px;
            }
            
            .detail-content {
                padding: 15px;
            }
            
            .content {
                gap: 10px;
            }
            
            .photo-container {
                height: 200px;
            }
            
            .info-section {
                padding: 15px;
            }
            
            .info-grid {
                grid-template-columns: 1fr;
                gap: 10px;
            }
            
            .info-item {
                padding: 12px;
            }
            
            .charts-container {
                gap: 10px;
            }
            
            .chart {
                height: 250px;
            }
            
            .ai-section {
                padding: 15px;
            }
            
            .ai-content-wrapper {
                padding: 15px;
            }
            
            .detail-title {
                font-size: 1.2rem;
            }
        }
        .container {
            height: 100%;
            margin: 0;
            padding: 0;
        }
        .content {
            height: 100%;
            display: flex;
            flex-direction: row;
            gap: 20px;
        }
        
        .left-panel {
            width: 350px;
            display: flex;
            flex-direction: column;
            gap: 15px;
            flex-shrink: 0;
        }
        
        .right-panel {
            flex: 1;
            display: flex;
            flex-direction: column;
            gap: 15px;
            overflow: hidden;
        }
        .photo-container {
            width: 100%;
            height: 250px;
            background-color: #f8f9fa;
            border-radius: 8px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
            display: flex;
            align-items: center;
            justify-content: center;
            overflow: hidden;
            position: relative;
            transition: all 0.3s ease;
            cursor: pointer;
        }
        .photo-container:hover {
            transform: translateY(-5px);
            box-shadow: 0 5px 15px rgba(0,0,0,0.2);
            background: #f0f2f5;
        }

        /* 触摸设备优化 */
        @media (hover: none) and (pointer: coarse) {
            .photo-container:hover {
                transform: none;
                box-shadow: 0 2px 8px rgba(0,0,0,0.1);
            }
            
            .photo-container:active {
                transform: scale(0.98);
            }
            
            .info-section:hover {
                transform: none;
            }
            
            .info-section:active {
                transform: scale(0.98);
            }
            
            .chart-item:hover {
                transform: none;
            }
            
            .chart-item:active {
                transform: scale(0.98);
            }
        }
        .baby-photo {
            width: 100%;
            height: 100%;
            object-fit: cover;
            background-color: #f8f9fa;
        }
        .info-section {
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
            display: flex;
            flex-direction: column;
            transition: all 0.3s ease;
        }
        .info-section:hover {
            transform: translateY(-5px);
            box-shadow: 0 5px 15px rgba(0,0,0,0.2);
            background: #f0f2f5;
        }

        /* .charts-container {
            background: white;
            padding: 35px;
            border-radius: 8px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
            height: 330px;
            display: flex;
            flex-direction: column;
        } */

        .info-section h3 {
            margin: 0 0 20px 0;
            color: #333;
            font-size: 1.3rem;
            padding-bottom: 12px;
            border-bottom: 2px solid #f0f0f0;
        }
        .info-grid {
            display: grid;
            grid-template-columns: repeat(3, 1fr);
            gap: 15px;
            flex: 1;
            align-content: start;
        }
        .info-item {
            display: flex;
            flex-direction: column;
            gap: 6px;
            padding: 15px;
            background: #f8f9fa;
            border-radius: 6px;
            transition: all 0.3s ease;
            height: fit-content;
        }
        .info-item:hover {
            background: #f0f0f0;
            transform: translateY(-2px);
        }
        .info-label {
            font-size: 0.9rem;
            color: #666;
            font-weight: 500;
        }
        .info-value {
            font-size: 1.2rem;
            color: #333;
            font-weight: 600;
        }
        .btn-back {
            padding: 8px 20px;
            background-color: #6c757d;
            color: white;
            border: none;
            border-radius: 6px;
            font-size: 1rem;
            cursor: pointer;
            transition: all 0.3s;
        }
        .btn-back:hover {
            background-color: #5a6268;
        }
        .photo-placeholder {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            width: 100%;
            height: 100%;
            background-color: #f8f9fa;
            color: #6c757d;
        }
        .photo-placeholder .icon {
            font-size: 4rem;
            margin-bottom: 15px;
        }
        .records-table {
            width: 100%;
            border-collapse: separate;
            border-spacing: 0;
            margin-top: 15px;
        }
        .records-table th,
        .records-table td {
            padding: 12px;
            border: 1px solid #ddd;
            text-align: left;
        }
        .records-table th {
            background-color: #e9ecef;
            font-weight: 600;
            color: #2c3e50;
        }
        .records-table tr:nth-child(even) {
            background-color: #f8f9fa;
        }
        .add-record-form {
            margin-top: 20px;
            padding: 20px;
            background-color: #fff;
            border-radius: 8px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
        }
        .form-grid {
            display: grid;
            grid-template-columns: repeat(3, 1fr);
            gap: 15px;
            margin-bottom: 15px;
        }
        .form-item {
            display: flex;
            flex-direction: column;
            gap: 5px;
        }
        .form-item label {
            font-weight: 600;
            color: #666;
        }
        .form-item input {
            padding: 8px;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-size: 1rem;
            width: 150px;
        }
        .form-item input:focus {
            border-color: #4CAF50;
            outline: none;
            box-shadow: 0 0 0 2px rgba(76,175,80,0.2);
        }
        .btn-add {
            background-color: #4CAF50;
            color: white;
            border: none;
            padding: 8px 20px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 1rem;
            transition: background-color 0.3s;
        }
        .btn-add:hover {
            background-color: #45a049;
        }
        .btn-delete {
            background-color: #f44336;
            color: white;
            border: none;
            padding: 4px 8px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 0.9rem;
            transition: background-color 0.3s;
        }
        .btn-delete:hover {
            background-color: #da190b;
        }
        .btn-maintain {
            background-color: #4CAF50;
            color: white;
            border: none;
            padding: 8px 20px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 1rem;
            transition: background-color 0.3s;
            margin-right: 10px;
        }
        .btn-maintain:hover {
            background-color: #45a049;
        }
        .header-actions {
            display: flex;
            align-items: center;
        }
        .modal-overlay {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: rgba(0, 0, 0, 0.5);
            display: flex;
            justify-content: center;
            align-items: center;
            z-index: 1000;
        }
        .modal-content {
            background: white;
            padding: 30px;
            border-radius: 8px;
            width: 90%;
            max-width: 600px;
            max-height: 90vh;
            overflow-y: auto;
        }

        /* 移动端模态框适配 */
        @media (max-width: 768px) {
            .modal-content {
                padding: 20px;
                width: 95%;
                max-height: 95vh;
            }
            
            .modal-title {
                font-size: 1.3rem;
            }
            
            .form-group input,
            .form-group select {
                font-size: 16px; /* 防止iOS缩放 */
                padding: 12px;
            }
            
            .form-group textarea {
                font-size: 16px;
                min-height: 100px;
            }
        }

        @media (max-width: 480px) {
            .modal-content {
                padding: 15px;
                width: 98%;
            }
            
            .modal-title {
                font-size: 1.2rem;
            }
            
            .form-group input,
            .form-group select,
            .form-group textarea {
                padding: 10px;
            }
        }
        .modal-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
        }
        .modal-title {
            font-size: 1.5rem;
            color: #333;
            margin: 0;
        }
        .modal-close {
            background: none;
            border: none;
            font-size: 1.5rem;
            cursor: pointer;
            color: #666;
            padding: 0;
        }
        .modal-close:hover {
            color: #333;
        }
        .charts-section {
            background: white;
            border-radius: 8px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
            padding: 20px;
            flex: 1;
            display: flex;
            flex-direction: column;
            overflow: hidden;
        }
        
        .charts-header {
            margin-bottom: 15px;
        }
        
        .charts-header h5 {
            margin: 0 0 10px 0;
            color: #333;
            font-size: 1.2rem;
        }
        
        .charts-container {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 15px;
            flex: 1;
            overflow: hidden;
        }

        /* 移动端图表适配 */
        @media (max-width: 768px) {
            .charts-container {
                gap: 20px;
                margin-top: 15px;
            }
            
            .chart-item {
                padding: 20px;
            }
            
            .chart {
                height: 350px;
            }
            
            .ai-section {
                padding: 20px;
                margin: 20px 0;
            }
            
            .ai-header {
                flex-direction: column;
                text-align: center;
                gap: 15px;
            }
            
            .ai-icon {
                font-size: 2rem;
                margin-right: 0;
                margin-bottom: 10px;
            }
            
            .ai-title h3 {
                font-size: 1.5rem;
            }
            
            .ai-content-wrapper {
                padding: 20px;
            }
            
            .ai-welcome {
                padding: 30px 15px;
            }
            
            .ai-welcome-icon {
                font-size: 3rem;
            }
            
            .ai-response-container {
                padding: 20px;
            }
        }

        @media (max-width: 480px) {
            .charts-container {
                gap: 15px;
            }
            
            .chart-item {
                padding: 15px;
            }
            
            .chart {
                height: 300px;
            }
            
            .ai-section {
                padding: 15px;
                margin: 15px 0;
            }
            
            .ai-title h3 {
                font-size: 1.3rem;
            }
            
            .ai-content-wrapper {
                padding: 15px;
            }
            
            .ai-welcome {
                padding: 20px 10px;
            }
            
            .ai-welcome-icon {
                font-size: 2.5rem;
            }
            
            .ai-response-container {
                padding: 15px;
            }
        }
        .chart-item {
            background: white;
            padding: 15px;
            border-radius: 8px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
            display: flex;
            flex-direction: column;
            transition: all 0.3s ease;
            overflow: hidden;
        }
        .chart-item:hover {
            transform: translateY(-5px);
            box-shadow: 0 5px 15px rgba(0,0,0,0.2);
            background: #f8f9fa;
        }
        .chart {
            width: 100%;
            height: 250px;
            flex: 1;
        }
        
        .photo-modal {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.9);
            z-index: 1000;
            justify-content: center;
            align-items: center;
        }

        .photo-modal.active {
            display: flex;
        }

        .photo-modal img {
            max-width: 90%;
            max-height: 90vh;
            object-fit: contain;
        }

        .photo-modal .close-btn {
            position: absolute;
            top: 20px;
            right: 20px;
            color: white;
            font-size: 30px;
            cursor: pointer;
            width: 40px;
            height: 40px;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 50%;
            background: rgba(255, 255, 255, 0.1);
            transition: all 0.3s ease;
        }

        .photo-modal .close-btn:hover {
            background: rgba(255, 255, 255, 0.2);
        }

        .ai-response {
            background: #f8f9fa;
            padding: 20px;
            border-radius: 8px;
            border-left: 4px solid #007bff;
        }
        
        .ai-content {
            line-height: 1.6;
            color: #333;
        }
        
        .ai-content p {
            margin-bottom: 10px;
        }
        
        .ai-content ul, .ai-content ol {
            margin-bottom: 10px;
            padding-left: 20px;
        }
        
        .ai-content li {
            margin-bottom: 5px;
        }
        
        .ai-content strong {
            color: #007bff;
        }
        
        .ai-content h1, .ai-content h2, .ai-content h3, .ai-content h4, .ai-content h5, .ai-content h6 {
            color: #007bff;
            margin-top: 15px;
            margin-bottom: 10px;
        }
        
        .spinner-border-sm {
            width: 1rem;
            height: 1rem;
        }
        
        .ai-section {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            border-radius: 12px;
            padding: 20px;
            margin: 0;
            box-shadow: 0 5px 15px rgba(0,0,0,0.1);
            color: white;
            flex-shrink: 0;
        }

        .ai-header {
            display: flex;
            align-items: center;
            margin-bottom: 15px;
        }

        .ai-icon {
            font-size: 2rem;
            margin-right: 15px;
            color: #ffd700;
        }

        .ai-title h3 {
            margin: 0;
            font-size: 1.4rem;
            font-weight: 600;
        }

        .ai-title p {
            margin: 3px 0 0 0;
            opacity: 0.9;
            font-size: 0.9rem;
        }

        .ai-content-wrapper {
            background: rgba(255,255,255,0.95);
            border-radius: 10px;
            padding: 20px;
            color: #333;
        }

        .ai-welcome {
            text-align: center;
            padding: 25px 15px;
        }

        .ai-welcome-content h4 {
            color: #333;
            margin: 15px 0 8px 0;
            font-weight: 600;
        }

        .ai-welcome-content p {
            color: #666;
            margin-bottom: 20px;
            font-size: 1rem;
        }

        .ai-welcome-icon {
            font-size: 3rem;
            color: #667eea;
            margin-bottom: 15px;
        }

        .ai-response-container {
            background: #f8f9fa;
            border-radius: 10px;
            padding: 20px;
        }

        .ai-response-header {
            border-bottom: 2px solid #e9ecef;
            padding-bottom: 12px;
            margin-bottom: 15px;
        }

        .ai-response-header h5 {
            margin: 0;
            color: #333;
            font-weight: 600;
        }

        .ai-response-content {
            line-height: 1.6;
            color: #333;
            font-size: 1rem;
            min-height: 120px;
            overflow-y: auto;
            background: #f8f9fa;
            border-radius: 8px;
            padding: 16px;
            position: relative;
            transition: box-shadow 0.2s;
        }
        .ai-response-content .ai-stream-chunk {
            display: block;
            margin-bottom: 6px;
            word-break: break-all;
        }
        .ai-thinking {
            display: flex;
            align-items: center;
            gap: 8px;
            margin-top: 10px;
            color: #667eea;
            font-size: 1.1rem;
            font-weight: 500;
        }
        .ai-thinking .dot {
            width: 8px;
            height: 8px;
            border-radius: 50%;
            background: #667eea;
            display: inline-block;
            animation: ai-blink 1.2s infinite both;
        }
        .ai-thinking .dot:nth-child(2) { animation-delay: 0.2s; }
        .ai-thinking .dot:nth-child(3) { animation-delay: 0.4s; }
        @keyframes ai-blink {
            0%, 80%, 100% { opacity: 0.2; }
            40% { opacity: 1; }
        }

        .ai-chat-section {
            margin-top: 20px;
            padding-top: 20px;
            border-top: 1px solid #e9ecef;
        }

        .ai-chat-header h6 {
            color: #333;
            font-weight: 600;
            margin-bottom: 5px;
        }

        .ai-chat-input {
            margin-top: 12px;
        }

        .ai-chat-input textarea {
            border-radius: 25px 0 0 25px;
            border: 2px solid #e9ecef;
            padding: 12px 16px;
            font-size: 1rem;
            min-height: 50px;
            max-height: 120px;
            resize: vertical;
            width: 100%;
            transition: border-color 0.2s;
        }

        /* 移动端AI输入框适配 */
        @media (max-width: 768px) {
            .ai-chat-input textarea {
                font-size: 16px; /* 防止iOS缩放 */
                padding: 12px 16px;
                min-height: 60px;
            }
            
            .ai-chat-input .btn {
                padding: 10px 20px;
                font-size: 14px;
            }
            
            .ai-chat-input .input-group {
                flex-direction: column;
            }
            
            .ai-chat-input textarea {
                border-radius: 15px 15px 0 0;
            }
            
            .ai-chat-input .btn {
                border-radius: 0 0 15px 15px;
                width: 100%;
            }
        }

        @media (max-width: 480px) {
            .ai-chat-input textarea {
                padding: 10px 12px;
                min-height: 50px;
            }
            
            .ai-chat-input .btn {
                padding: 8px 16px;
                font-size: 13px;
            }
        }

        .ai-chat-input textarea:focus {
            border-color: #667eea;
            box-shadow: 0 0 0 0.2rem rgba(102, 126, 234, 0.15);
        }

        .ai-chat-input .btn {
            border-radius: 0 25px 25px 0;
            border: 2px solid #667eea;
            padding: 12px 25px;
            font-weight: 500;
        }

        .ai-chat-input .btn:hover {
            background-color: #667eea;
            border-color: #667eea;
        }

        .btn-lg {
            padding: 12px 24px;
            font-size: 1rem;
            border-radius: 50px;
            font-weight: 500;
        }

        /* 移动端按钮适配 */
        @media (max-width: 768px) {
            .btn-lg {
                padding: 12px 24px;
                font-size: 1rem;
            }
            
            .header-actions {
                flex-direction: column;
                gap: 10px;
            }
            
            .btn-maintain,
            .btn-back {
                width: 100%;
                padding: 12px;
                font-size: 14px;
            }
        }

        @media (max-width: 480px) {
            .btn-lg {
                padding: 10px 20px;
                font-size: 0.9rem;
            }
            
            .btn-maintain,
            .btn-back {
                padding: 10px;
                font-size: 13px;
            }
        }

        .main-grid {
            display: grid;
            grid-template-columns: 2fr 1fr;
            grid-gap: 24px;
            height: 100%;
        }
        .main-left {
            display: grid;
            grid-template-rows: 1fr 2fr 2fr;
            grid-gap: 18px;
            height: 100%;
        }
        .main-left-top {
            display: flex;
            flex-direction: row;
            gap: 18px;
            height: 100%;
        }
        .main-photo {
            flex: 2 1 0;
            min-width: 0;
            aspect-ratio: 1 / 1; /* 保证正方形 */
            display: flex;
            align-items: center;
            justify-content: center;
            background: #f8f9fa;
            border-radius: 8px;
            overflow: hidden;
            height: auto !important;
            max-height: none !important;
            cursor: pointer;
        }
        .main-photo img.baby-photo {
            width: 100%;
            height: 100%;
            object-fit: cover;
            display: block;
        }
        .main-info {
            flex: 7 1 0;
            min-width: 0;
            background: #fff;
            border-radius: 8px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.08);
            padding: 18px 18px 10px 18px;
            display: flex;
            flex-direction: column;
            justify-content: center;
        }
        .main-left-middle, .main-left-bottom {
            display: flex;
            flex-direction: column;
            justify-content: center;
        }
        .main-right {
            height: 100%;
            display: flex;
            flex-direction: column;
            justify-content: flex-start;
        }
        .ai-section {
            flex: 1 1 0;
            min-height: 0;
            display: flex;
            flex-direction: column;
        }
        .chart-item {
            height: 100%;
            min-height: 0;
            display: flex;
            flex-direction: column;
            background: #fff;
            border-radius: 8px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.08);
            padding: 0;
        }
        .chart-title {
            font-size: 1.1rem;
            font-weight: 600;
            margin-bottom: 6px;
            color: #333;
            padding: 12px 12px 0 12px;
        }
        .chart {
            flex: 1 1 0;
            min-height: 0;
            width: 100%;
            height: 100%;
            box-sizing: border-box;
            margin: 0;
        }
        @media (max-width: 1100px) {
            .main-grid {
                grid-template-columns: 1fr;
            }
            .main-right {
                margin-top: 18px;
            }
        }
        @media (max-width: 768px) {
            .main-grid {
                grid-template-columns: 2fr 1fr;;
                grid-gap: 12px;
            }
            .main-left {
                grid-template-rows: 1fr 2fr 2fr;
                grid-gap: 10px;
            }
            .main-left-top {
                flex-direction: column;
                gap: 10px;
            }
            .main-photo, .main-info {
                min-height: 0;
                height: 100px;
            }
        }
        .btn-change-photo {
            background-color: #4CAF50;
            color: white;
            border: none;
            padding: 8px 20px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 1rem;
            transition: background-color 0.3s;
            margin-right: 10px;
        }
        .btn-change-photo:hover {
            background-color: #45a049;
        }
        .ai-response-content table {
            width: 100%;
            border-collapse: collapse;
        }
        .ai-response-content th, .ai-response-content td {
            border: 1px solid #ccc;
            padding: 6px 10px;
        }
        .ai-response-content th {
            background: #f0f0f0;
            font-weight: 600;
        }
    </style>
</head>
<body>
    <div id="app" v-cloak>
        <div v-if="baby && baby.photo !== undefined" class="detail-page">
            <div class="detail-header">
                <div class="header-left">
                <h2 class="detail-title">{{ baby && baby.name ? (baby.name + ' 的成长记录') : '' }}</h2>
                </div>
                <div class="header-right">
                    <div class="user-info" v-if="currentUser">
                        <span class="user-email">{{ currentUser.email }}</span>
                        <button class="btn btn-outline-primary btn-sm" @click="goToChangePassword">
                            <i class="bi bi-shield-lock"></i>
                            修改密码
                        </button>
                        <button class="btn btn-outline-secondary btn-sm" @click="logout">
                            <i class="bi bi-box-arrow-right"></i>
                            退出登录
                        </button>
                    </div>
                <div class="header-actions">
                    <button class="btn-maintain" @click="showMaintainModal = true">维护身高体重</button>
                        <button class="btn-change-photo" @click="changePhoto(baby)"><i class="bi bi-image"></i> 更换照片</button>
                    <button class="btn-back" @click="goBack">返回</button>
                </div>
            </div>
            </div>
            <div class="detail-content main-grid">
                <!-- 左侧2/3 -->
                <div class="main-left">
                    <div class="main-left-top">
                        <div class="main-photo" @click="showFullPhoto">
                            <img :src="getPhotoUrl(baby && baby.photo ? baby.photo : '')" :alt="baby && baby.name ? (baby.name + '的照片') : ''" class="baby-photo">
                        </div>
                        <!-- 更换照片按钮，点击后可上传新照片 -->
                        <div style="margin-top: 10px; text-align: center;" v-if="false">
                            <button class="btn btn-outline-primary btn-sm" @click.stop="changePhoto(baby)">
                                <i class="bi bi-image"></i> 更换照片
                            </button>
                        </div>
                        <div class="main-info">
                            <h3>基本信息</h3>
                            <div class="info-grid">
                                <div class="info-item">
                                    <span class="info-label">姓名</span>
                                    <span class="info-value">{{ baby && baby.name ? baby.name : '' }}</span>
                                </div>
                                <div class="info-item">
                                    <span class="info-label">性别</span>
                                    <span class="info-value">{{ baby && baby.gender ? baby.gender : '' }}</span>
                                </div>
                                <div class="info-item">
                                    <span class="info-label">出生日期</span>
                                    <span class="info-value">{{ baby && baby.birth_date ? baby.birth_date : '' }}</span>
                                </div>
                                <div class="info-item">
                                    <span class="info-label">出生体重</span>
                                    <span class="info-value">{{ getBirthRecord('weight') }}kg</span>
                                </div>
                                <div class="info-item">
                                    <span class="info-label">出生身高</span>
                                    <span class="info-value">{{ getBirthRecord('height') }}cm</span>
                                </div>
                                <div class="info-item">
                                    <span class="info-label">年龄</span>
                                    <span class="info-value">{{ baby && baby.birth_date ? calculateAge(baby.birth_date) : '' }}</span>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="main-left-middle">
                            <div class="chart-item">
                                <div class="chart-title">身高-年龄曲线</div>
                                <div id="heightAgeChart" class="chart"></div>
                            </div>
                    </div>
                    <div class="main-left-bottom">
                            <div class="chart-item">
                                <div class="chart-title">体重-年龄曲线</div>
                                <div id="weightAgeChart" class="chart"></div>
                            </div>
                            </div>
                        </div>
                <!-- 右侧1/3 -->
                <div class="main-right">
                    <div class="ai-section">
                        <div class="ai-header">
                            <div class="ai-icon">
                                <i class="bi bi-robot"></i>
                    </div>
                            <div class="ai-title">
                                <h3>AI智能解读与建议</h3>
                                <p>基于宝宝信息和生长记录，AI提供专业的生长发育分析</p>
                            </div>
                        </div>
                        <div class="ai-content-wrapper">
                            <div v-if="!aiStarted" class="ai-welcome">
                                <div class="ai-welcome-content">
                                    <div class="ai-welcome-icon">
                                        <i class="bi bi-lightbulb"></i>
                                    </div>
                                    <h4>智能分析宝宝生长发育</h4>
                                    <p>AI将分析宝宝的生长曲线、营养状况，并提供个性化建议</p>
                                    <button class="btn btn-primary btn-lg" @click="onStartAIAnalysis" :disabled="aiLoading">
                                        <span v-if="aiLoading" class="spinner-border spinner-border-sm me-2"></span>
                                        <i v-else class="bi bi-play-circle me-2"></i>
                                        {{ aiLoading ? 'AI分析中...' : '开始AI分析' }}
                                    </button>
                                </div>
                            </div>
                            <div v-if="aiStarted" class="ai-response-container">
                                <div class="ai-response-header">
                                    <h5><i class="bi bi-check-circle-fill text-success me-2"></i>AI解读结果</h5>
                                </div>
                                <div class="ai-response-content" style="background:#fff;color:#000;min-height:200px;">
                                    <div v-html="aiRendered"></div>
                                </div>
                                <div class="ai-chat-section">
                                    <div class="ai-chat-header">
                                        <h6><i class="bi bi-chat-dots me-2"></i>继续咨询</h6>
                                        <p class="text-muted small">您可以继续向AI提问，获得更详细的建议</p>
                                    </div>
                                    <div class="ai-chat-input">
                                        <div class="input-group">
                                            <textarea v-model="userQuestion"
                                                      placeholder="请输入您的问题，例如：宝宝最近不爱吃饭怎么办？"
                                                      @keyup.enter.ctrl="streamAIAnalysis"
                                                      :disabled="aiLoading"></textarea>
                                            <button class="btn btn-outline-primary" @click="streamAIAnalysis" :disabled="aiLoading">
                                                <span v-if="aiLoading" class="spinner-border spinner-border-sm me-2"></span>
                                                <i v-else class="bi bi-send me-2"></i>
                                                发送
                                            </button>
                                        </div>
                                        <div class="text-muted small mt-1">按 <kbd>Ctrl+Enter</kbd> 发送</div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <div v-else style="text-align:center;padding:40px 0;">
            <span>正在加载宝宝信息...</span>
        </div>

        <!-- 维护弹框 -->
        <div class="modal-overlay" v-if="showMaintainModal">
            <div class="modal-content">
                <div class="modal-header">
                    <h3 class="modal-title">维护身高体重记录</h3>
                    <button class="modal-close" @click="showMaintainModal = false">&times;</button>
                </div>
                <div class="add-record-form">
                    <div class="form-grid">
                        <div class="form-item">
                            <label>日期</label>
                            <input type="date" v-model="newRecord.date">
                        </div>
                        <div class="form-item">
                            <label>身高 (cm)</label>
                            <input type="number" v-model="newRecord.height" step="0.1" placeholder="请输入身高">
                        </div>
                        <div class="form-item">
                            <label>体重 (kg)</label>
                            <input type="number" v-model="newRecord.weight" step="0.1" placeholder="请输入体重">
                        </div>
                    </div>
                    <button class="btn-add" @click="addRecord">添加记录</button>
                </div>
                <table class="records-table">
                    <thead>
                        <tr>
                            <th>日期</th>
                            <th>身高 (cm)</th>
                            <th>体重 (kg)</th>
                            <th>操作</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr v-for="record in baby.records" :key="record.id">
                            <td>{{ record && record.date ? record.date : '' }}</td>
                            <td>{{ record && record.height ? record.height : '' }}</td>
                            <td>{{ record && record.weight ? record.weight : '' }}</td>
                            <td>
                                <button class="btn-delete" @click="deleteRecord(record.id)">删除</button>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>

        <!-- 照片查看模态框 -->
        <div class="photo-modal" :class="{ active: showPhotoModal }" @click.self="closePhotoModal">
            <div class="close-btn" @click="closePhotoModal">&times;</div>
            <img :src="getPhotoUrl(baby.photo)" :alt="baby.name + '的照片'">
        </div>
    </div>
    <script src="js/vue.min.js"></script>
    <script src="js/axios.min.js"></script>
    <script src="js/moment.min.js"></script>
    <script src="js/moment-zh-cn.js"></script>
    <script src="js/sweetalert2.all.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
    <script>
        // 添加axios响应拦截器，自动处理登录过期
        axios.interceptors.response.use(function (response) {
            // 正常响应直接返回
            return response;
        }, function (error) {
            // 如果返回401，说明登录状态已过期或无效
            if (error.response && error.response.status === 401) {
                // 清除本地token，跳转到登录页面
                localStorage.removeItem('token');
                localStorage.removeItem('user');
                window.location.href = 'login.html';
            }
            // 其他错误继续抛出
            return Promise.reject(error);
        });
        new Vue({
            el: '#app',
            data() {
                return {
                baby: {},
                    currentUser: null,
                newRecord: {
                    date: new Date().toISOString().split('T')[0],
                    height: '',
                    weight: ''
                },
                charts: {
                    heightAge: null,
                    weightAge: null,
                    heightWeight: null
                },
                showMaintainModal: false,
                    showPhotoModal: false,
                    aiLoading: false,
                    aiResponse: null,
                    userQuestion: '',
                    aiChunks: [], // AI流式分段内容
                    aiStarted: false,
                    aiRendered: '',    // 最终整体渲染的HTML
                    aiBuffer: '',     // 累积所有内容
                };
            },
            computed: {
                aiMergedChunks() {
                    // 合并同类型内容
                    if (!this.aiChunks.length) return [];
                    const merged = [];
                    let last = null;
                    this.aiChunks.forEach(chunk => {
                        if (!last || last.type !== chunk.type) {
                            last = { type: chunk.type, content: chunk.content || '' };
                            merged.push(last);
                        } else {
                            last.content += chunk.content || '';
                        }
                    });
                    return merged;
                },
                aiFinalAnswer() {
                    // 合并所有answer类型内容
                    return this.aiChunks
                        .filter(chunk => chunk.type === 'answer')
                        .map(chunk => chunk.content || '')
                        .join('');
                },
                aiFinalReasoning() {
                    // 合并所有reasoning类型内容
                    return this.aiChunks
                        .filter(chunk => chunk.type === 'reasoning')
                        .map(chunk => chunk.content || '')
                        .join('');
                }
            },
            created() {
                this.checkAuth();
            },

            methods: {
                // 检查用户认证状态
                checkAuth() {
                    const token = localStorage.getItem('token');
                    const user = localStorage.getItem('user');
                    
                    if (!token || !user) {
                        // 未登录，跳转到登录页面
                        window.location.href = 'login.html';
                        return;
                    }
                    
                    try {
                        this.currentUser = JSON.parse(user);
                        // 设置axios默认headers
                        axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
                        // 获取宝宝信息
                const urlParams = new URLSearchParams(window.location.search);
                const babyId = urlParams.get('id');
                if (babyId) {
                    this.fetchBaby(babyId);
                        }
                    } catch (error) {
                        console.error('解析用户信息失败:', error);
                        this.logout();
                    }
                },
                
                // 退出登录
                logout() {
                    localStorage.removeItem('token');
                    localStorage.removeItem('user');
                    window.location.href = 'login.html';
                },
                
                // 跳转到修改密码页面
                goToChangePassword() {
                    window.location.href = 'change-password.html';
                },
                
                getPhotoUrl(photo) {
                    if (!photo) return '';
                    // 如果是完整URL，直接返回
                    if (photo.startsWith('http://') || photo.startsWith('https://')) {
                        // 如果是本地开发的地址，强制替换为线上API域名
                        const apiRoot = window.API_BASE.replace(/\/api$/, '');
                        if (photo.includes('localhost')) {
                            // 提取 /uploads/xxx.jpg 部分
                            const idx = photo.indexOf('/uploads/');
                            if (idx !== -1) {
                                return `${apiRoot}${photo.substring(idx)}`;
                            }
                        }
                        return photo;
                    }
                    // 否则拼接 window.API_BASE 的主域名部分
                    const apiRoot = window.API_BASE.replace(/\/api$/, '');
                    return `${apiRoot}${photo.startsWith('/') ? '' : '/'}${photo}`;
                },
                fetchBaby(id) {
                    axios.get(`${window.API_BASE}/babies/${id}`)
                        .then(response => {
                            this.baby = response.data;
                            this.fetchRecords(id);
                        })
                        .catch(error => {
                            console.error('获取宝宝信息失败:', error);
                            Swal.fire('获取失败', '请重试', 'error');
                        });
                },
                fetchRecords(babyId) {
                    axios.get(`${window.API_BASE}/babies/${babyId}/records`)
                        .then(response => {
                            // 使用Vue.set确保响应式更新
                            this.$set(this.baby, 'records', response.data);
                            // 强制更新视图，确保出生身高体重能正确显示
                            this.$forceUpdate();
                            this.$nextTick(() => {
                                this.initCharts();
                            });
                        })
                        .catch(error => {
                            console.error('获取记录失败:', error);
                            Swal.fire('获取记录失败', '请重试', 'error');
                        });
                },
                initCharts() {
                    if (!this.baby || !this.baby.records || this.baby.records.length === 0) {
                        return;
                    }

                    // 计算年龄（月）
                    const birthDate = moment(this.baby.birth_date);
                    const records = this.baby.records.map(record => {
                        const recordDate = moment(record.date);
                        const ageInMonths = recordDate.diff(birthDate, 'months', true);
                        return {
                        ...record,
                            age: parseFloat(ageInMonths.toFixed(1))
                        };
                    }).sort((a, b) => a.age - b.age);

                    // 加载标准生长曲线数据
                    const gender = this.baby.gender === '男' ? 'boy' : 'gril';
                    axios.get(`${window.API_BASE}/config/growth_curve_${gender}.json`)
                        .then(response => {
                            const standardData = response.data.growth_curve.percentile_data;

                            // 插值计算函数
                            function interpolateValue(age, data, percentile) {
                                // 找到最接近的两个数据点
                                let lower = null;
                                let upper = null;
                                
                                for (let i = 0; i < data.length; i++) {
                                    const currentAge = parseInt(data[i].age_months);
                                    if (currentAge <= age) {
                                        lower = data[i];
                                    }
                                    if (currentAge >= age) {
                                        upper = data[i];
                                        break;
                                    }
                                }

                                // 如果年龄超出范围，使用边界值
                                if (!lower) return data[0].height[percentile];
                                if (!upper) return data[data.length - 1].height[percentile];
                                if (lower === upper) return lower.height[percentile];

                                // 线性插值计算
                                const lowerAge = parseInt(lower.age_months);
                                const upperAge = parseInt(upper.age_months);
                                const lowerValue = lower.height[percentile];
                                const upperValue = upper.height[percentile];
                                
                                return lowerValue + (upperValue - lowerValue) * (age - lowerAge) / (upperAge - lowerAge);
                            }

                            // 获取指定月龄的参考数据
                            function getReferenceValues(age, data) {
                                return {
                                    p3: interpolateValue(age, data, '3rd'),
                                    p50: interpolateValue(age, data, '50th'),
                                    p97: interpolateValue(age, data, '97th')
                                };
                            }

                    // 身高-年龄图表
                    this.charts.heightAge = echarts.init(document.getElementById('heightAgeChart'));
                    this.charts.heightAge.setOption({
                        grid: {
                            left: '2%',
                            right: '2%',
                            top: 40,
                            bottom: 40,
                            containLabel: true
                        },
                        tooltip: {
                            trigger: 'axis',
                            formatter: function(params) {
                                        // 找到实际身高数据点
                                        const actualData = params.find(p => p.seriesName === '实际身高');
                                        if (!actualData) return '';

                                        const age = actualData.value[0];
                                        const height = actualData.value[1];
                                        const refValues = getReferenceValues(age, standardData);

                                        return `年龄: ${age.toFixed(1)}个月<br/>` +
                                               `实际身高: ${height.toFixed(1)}cm<br/>` +
                                               `参考值:<br/>` +
                                               `P3: ${refValues.p3.toFixed(1)}cm<br/>` +
                                               `P50: ${refValues.p50.toFixed(1)}cm<br/>` +
                                               `P97: ${refValues.p97.toFixed(1)}cm`;
                                    }
                                },
                                legend: {
                                    data: ['实际身高', 'P3', 'P50', 'P97']
                                },
                        xAxis: {
                            type: 'value',
                            name: '年龄(月)',
                            nameLocation: 'middle',
                                    nameGap: 30,
                                    min: 0,
                                    max: 60,
                                    interval: 1,
                                    axisLabel: {
                                        formatter: function(value) {
                                            return value.toFixed(0);
                                        }
                                    }
                        },
                        yAxis: {
                            type: 'value',
                            name: '身高(cm)',
                            nameLocation: 'middle',
                            nameGap: 30
                        },
                                series: [
                                    {
                                        name: '实际身高',
                            data: records.map(r => [r.age, r.height]),
                            type: 'line',
                            smooth: true,
                            symbol: 'circle',
                            symbolSize: 8,
                            itemStyle: {
                                color: '#4CAF50'
                            }
                                    },
                                    {
                                        name: 'P3',
                                        data: standardData.map(d => [parseInt(d.age_months), d.height['3rd']]),
                                        type: 'line',
                                        smooth: true,
                                        symbol: 'none',
                                        lineStyle: {
                                            color: '#FF9800',
                                            type: 'dashed'
                                        }
                                    },
                                    {
                                        name: 'P50',
                                        data: standardData.map(d => [parseInt(d.age_months), d.height['50th']]),
                                        type: 'line',
                                        smooth: true,
                                        symbol: 'none',
                                        lineStyle: {
                                            color: '#2196F3',
                                            type: 'dashed'
                                        }
                                    },
                                    {
                                        name: 'P97',
                                        data: standardData.map(d => [parseInt(d.age_months), d.height['97th']]),
                                        type: 'line',
                                        smooth: true,
                                        symbol: 'none',
                                        lineStyle: {
                                            color: '#FF9800',
                                            type: 'dashed'
                                        }
                                    }
                                ]
                    });

                    // 体重-年龄图表
                    this.charts.weightAge = echarts.init(document.getElementById('weightAgeChart'));
                    this.charts.weightAge.setOption({
                        grid: {
                            left: '2%',
                            right: '2%',
                            top: 40,
                            bottom: 40,
                            containLabel: true
                        },
                        tooltip: {
                            trigger: 'axis',
                            formatter: function(params) {
                                        // 找到实际体重数据点
                                        const actualData = params.find(p => p.seriesName === '实际体重');
                                        if (!actualData) return '';

                                        const age = actualData.value[0];
                                        const weight = actualData.value[1];
                                        const refValues = getReferenceValues(age, standardData);

                                        return `年龄: ${age.toFixed(1)}个月<br/>` +
                                               `实际体重: ${weight.toFixed(1)}kg<br/>` +
                                               `参考值:<br/>` +
                                               `P3: ${refValues.p3.toFixed(1)}kg<br/>` +
                                               `P50: ${refValues.p50.toFixed(1)}kg<br/>` +
                                               `P97: ${refValues.p97.toFixed(1)}kg`;
                                    }
                                },
                                legend: {
                                    data: ['实际体重', 'P3', 'P50', 'P97']
                                },
                        xAxis: {
                            type: 'value',
                            name: '年龄(月)',
                            nameLocation: 'middle',
                                    nameGap: 30,
                                    min: 0,
                                    max: 60,
                                    interval: 1,
                                    axisLabel: {
                                        formatter: function(value) {
                                            return value.toFixed(0);
                                        }
                                    }
                        },
                        yAxis: {
                            type: 'value',
                            name: '体重(kg)',
                            nameLocation: 'middle',
                            nameGap: 30
                        },
                                series: [
                                    {
                                        name: '实际体重',
                            data: records.map(r => [r.age, r.weight]),
                            type: 'line',
                            smooth: true,
                            symbol: 'circle',
                            symbolSize: 8,
                            itemStyle: {
                                color: '#2196F3'
                            }
                                    },
                                    {
                                        name: 'P3',
                                        data: standardData.map(d => [parseInt(d.age_months), d.weight['3rd']]),
                                        type: 'line',
                                        smooth: true,
                                        symbol: 'none',
                                        lineStyle: {
                                            color: '#FF9800',
                                            type: 'dashed'
                                        }
                                    },
                                    {
                                        name: 'P50',
                                        data: standardData.map(d => [parseInt(d.age_months), d.weight['50th']]),
                                        type: 'line',
                                        smooth: true,
                                        symbol: 'none',
                                        lineStyle: {
                                            color: '#2196F3',
                                            type: 'dashed'
                                        }
                                    },
                                    {
                                        name: 'P97',
                                        data: standardData.map(d => [parseInt(d.age_months), d.weight['97th']]),
                            type: 'line',
                            smooth: true,
                                        symbol: 'none',
                                        lineStyle: {
                                            color: '#FF9800',
                                            type: 'dashed'
                                        }
                                    }
                                ]
                    });

                    // 监听窗口大小变化，调整图表大小
                    window.addEventListener('resize', () => {
                        Object.values(this.charts).forEach(chart => {
                            chart && chart.resize();
                        });
                            });
                        })
                        .catch(error => {
                            console.error('加载标准生长曲线数据失败:', error);
                            Swal.fire('加载失败', '无法加载标准生长曲线数据', 'error');
                    });
                },
                addRecord() {
                    if (!this.newRecord.date || !this.newRecord.height || !this.newRecord.weight) {
                        Swal.fire('提示', '请填写完整的记录信息', 'warning');
                        return;
                    }
                    axios.post(`${window.API_BASE}/babies/${this.baby.id}/records`, this.newRecord)
                        .then(response => {
                            this.baby.records.unshift(response.data);
                            this.newRecord = {
                                date: new Date().toISOString().split('T')[0],
                                height: '',
                                weight: ''
                            };
                            // 使用Vue.set确保响应式更新
                            this.$set(this.baby, 'records', [...this.baby.records]);
                            // 强制更新视图，确保出生身高体重能正确显示
                            this.$forceUpdate();
                            this.$nextTick(() => {
                                this.initCharts();
                            });
                            Swal.fire('成功', '记录已添加', 'success');
                        })
                        .catch(error => {
                            console.error('添加记录失败:', error);
                            Swal.fire('添加失败', '请重试', 'error');
                        });
                },
                deleteRecord(recordId) {
                    Swal.fire({
                        title: '确定要删除这条记录吗？',
                        text: '此操作不可恢复！',
                        icon: 'warning',
                        showCancelButton: true,
                        confirmButtonText: '确定',
                        cancelButtonText: '取消'
                    }).then((result) => {
                        if (result.isConfirmed) {
                            axios.delete(`${window.API_BASE}/babies/${this.baby.id}/records/${recordId}`)
                                .then(() => {
                                    this.baby.records = this.baby.records.filter(r => r.id !== recordId);
                                    // 使用Vue.set确保响应式更新
                                    this.$set(this.baby, 'records', [...this.baby.records]);
                                    // 强制更新视图，确保出生身高体重能正确显示
                                    this.$forceUpdate();
                                    this.$nextTick(() => {
                                        this.initCharts();
                                    });
                                    Swal.fire('已删除！', '', 'success');
                                })
                                .catch(error => {
                                    console.error('删除记录失败:', error);
                                    Swal.fire('删除失败', '请重试', 'error');
                                });
                        }
                    });
                },
                goBack() {
                    window.location.href = 'index.html';
                },
                calculateAge(birthDate) {
                    const birth = moment(birthDate);
                    const now = moment();
                    const years = now.diff(birth, 'years');
                    const months = now.diff(birth, 'months') % 12;
                    if (years > 0) {
                        return `${years}岁${months}个月`;
                    } else {
                        return `${months}个月`;
                    }
                },
                getBirthRecord(type) {
                    if (!this.baby || !this.baby.records || this.baby.records.length === 0) {
                        return '-';
                    }
                    // 首先尝试查找与出生日期完全匹配的记录
                    let birthRecord = this.baby.records.find(record => record.date === this.baby.birth_date);
                    // 只返回完全匹配的出生当天记录，否则返回'-'
                    return birthRecord ? birthRecord[type] : '-';
                },
                showFullPhoto() {
                    this.showPhotoModal = true;
                },
                closePhotoModal() {
                    this.showPhotoModal = false;
                },
                getAIAnalysis() {
                    this.aiLoading = true;
                    axios.post(`${window.API_BASE}/babies/${this.baby.id}/ai-analysis`)
                        .then(response => {
                            if (response.data.success) {
                                this.aiResponse = response.data.message;
                            } else {
                                Swal.fire('获取失败', response.data.message, 'error');
                            }
                            this.aiLoading = false;
                        })
                        .catch(error => {
                            console.error('获取AI分析失败:', error);
                            Swal.fire('获取失败', '请重试', 'error');
                            this.aiLoading = false;
                        });
                },
                formatAIResponse(response) {
                    // 使用marked渲染markdown
                    if (window.marked) {
                        return marked.parse(response || '');
                    }
                    return response.replace(/\n/g, '<br>');
                },
                async streamAIAnalysis() {
                    this.aiLoading = true;
                    this.aiResponse = '';
                    this.aiChunks = [];
                    this.aiRendered = '';
                    this.aiBuffer = '';
                    const controller = new AbortController();
                    const token = localStorage.getItem('token');
                    try {
                        const response = await fetch(`${window.API_BASE}/babies/${this.baby.id}/ai-analysis`, {
                            method: 'POST',
                            headers: {
                                'Content-Type': 'application/json',
                                'Authorization': `Bearer ${token}`
                            },
                            body: JSON.stringify({ message: this.userQuestion }),
                            signal: controller.signal
                        });
                        if (!response.ok) {
                            throw new Error('AI接口请求失败');
                        }
                        const reader = response.body.getReader();
                        const decoder = new TextDecoder('utf-8');
                        while (true) {
                            let buffer = '';
                            const { done, value } = await reader.read();
                            if (done) break;
                            buffer = decoder.decode(value, { stream: true });
                            // 流式期间只累积文本
                            this.aiBuffer += buffer;
                            // 流式期间实时格式化渲染
                            if (window.marked) {
                                marked.setOptions({ gfm: true, breaks: true });
                                this.aiRendered = marked.parse(this.aiBuffer);
                            } else {
                                this.aiRendered = this.aiBuffer.replace(/\n/g, '<br>');
                            }
                            this.$nextTick(() => {
                                const el = document.querySelector('.ai-response-content');
                                if (el) el.scrollTop = el.scrollHeight;
                            });
                        }
                        // 结束后整体渲染
                        if (this.aiBuffer && this.aiBuffer.trim()) {
                            if (window.marked) {
                                console.log('完整的Markdown内容:', this.aiBuffer );
                                marked.setOptions({ gfm: true, breaks: true });
                                // 表格前后加空行
                                let md = this.aiBuffer;
                                this.aiRendered = marked.parse(md);
                            } else {
                                this.aiRendered = this.aiBuffer.replace(/\n/g, '<br>');
                            }
                            this.aiBuffer = '';
                        }
                        this.userQuestion = '';
                    } catch (error) {
                        console.error('AI流式对话失败:', error);
                        Swal.fire('获取失败', error.message || '请重试', 'error');
                    } finally {
                        this.aiLoading = false;
                    }
                },
                formatAIChunk(chunk, idx) {
                    let label = '';
                    if (chunk.type === 'reasoning' && idx === 0) {
                        label = '<span style="color:#888;font-size:0.95em;">【思考过程】</span><br>';
                    } else if (chunk.type === 'answer' && idx === 0) {
                        label = '<span style="color:#007bff;font-size:0.95em;">【AI回复】</span><br>';
                    } else if (chunk.type === 'error') {
                        label = '<span style="color:red;font-size:0.95em;">【AI错误】</span><br>';
                    }
                    let content = chunk.content || '';
                    // markdown预处理：标题、列表、表格前后加空行，去除多余空格
                    content = content
                        .replace(/(#+ .+)/g, '\n$1\n') // 标题前后加空行
                        .replace(/([-*] .+)/g, '\n$1') // 列表项前加空行
                        .replace(/\n{2,}/g, '\n\n')   // 多余换行合并
                        .replace(/\s+$/gm, '');       // 行尾空格去除
                    if (window.marked) {
                        content = marked.parse(content);
                    } else {
                        content = content.replace(/\n/g, '<br>');
                    }
                    return label + content;
                },
                async changePhoto(baby) {
                    const input = document.createElement('input');
                    input.type = 'file';
                    input.accept = 'image/*';
                    input.onchange = async (e) => {
                        const file = e.target.files[0];
                        if (!file) return;
                        const formData = new FormData();
                        formData.append('file', file);
                        try {
                            const response = await axios.post(
                                `${window.API_BASE}/babies/${baby.id}/photo`,
                                formData,
                                { headers: { 'Content-Type': 'multipart/form-data' } }
                            );
                            if (response.data.success) {
                                baby.photo = response.data.photo;
                                this.$forceUpdate && this.$forceUpdate();
                                Swal.fire('照片更新成功', '', 'success');
                            } else {
                                Swal.fire('照片更新失败', response.data.error || '', 'error');
                            }
                        } catch (err) {
                            Swal.fire('照片更新失败', err.response?.data?.error || '', 'error');
                        }
                    };
                    input.click();
                },
                onStartAIAnalysis() {
                    this.aiStarted = true;
                    this.streamAIAnalysis();
                }
            }
        });
    </script>
</body>
</html> 